// -----------------------------------------------------------------------------------
// ImageSlider v1.6
// by Travis Beck - http://wholewheatcreative.com
// Last Modification: 12/29/08
//
//	
// Requires MooTools v1.2 - http://mootools.net/
//
// =========USAGE=========
// var mySlider = new ImageSlider({
//    objToSlide: 'sliderHolder',            //REQUIRED (String)   - The id of the holder element that will be sliding
//    sliderElements: 'div',                 //REQUIRED (String)   - The type of elements contained within the slider can be any html element(div, p, a, span)
//    numOfElementsToSlide: 2,               //OPTIONAL (Number)   - Number of elements to slide
//    leftBtn: 'slideLeftBtn',               //REQUIRED (String)   - The ID of the element that when clicked will slide your imageslider left
//    rightBtn: 'slideRightBtn',             //REQUIRED (String)   - The ID of the element that when clicked will slide your imageslider right
//    easing: Fx.Transitions.Expo.easeInOut, //OPTIONAL (Function) - The type of easing to use on transition (more info on easing http://mootools.net/docs/Fx/Fx.Transitions#Fx-Transitions)
//    useMouseWheel: true							//OPTIONAL (Boolean)  - Whether or not the mouse wheel scrolls when over the section
//    onSlideComplete: function(index){      //OPTIONAL (Function) - Callback Function to fire once sliding is completed. returns index.
//       //index is the current position
//    },
//		isHorizontal: true							//OPTIONAL (boolean)	 -  Set to false in order to allow vertical functionality.			
// });
// 
// =========PUBLIC FUNCTIONS=========
// mySlider.slideTo(position:Number);
//
// Slides to the position provided. 
// Position is the number of the element you want to slide to
//
// =========CALLBACKS=========
// onSlideComplete(index:Number)
//
// Called after the slide animation has completed
// -----------------------------------------------------------------------------------

var ImageSlider = new Class({
   Implements: [Options, Events],
   options: {
      objToSlide: '',
      sliderElements: '', /* can be any html element (div, p, a, span) */
      numOfElementsToSlide: 2, /* this is the number of elements that slide when the button is hit */
      numOfElementsShown: 0, /* this is the total number of elements shown at any give time */
      leftBtn: '',
      rightBtn: '',
      isHorizontal: true,
      easing: Fx.Transitions.Expo.easeInOut,
      useMouseWheel: true
      //onSlideComplete: $empty
   },
   initialize: function(options){
      this.setOptions(options);
      this.options.objToSlide = $(this.options.objToSlide);
      if(!(this.options.objToSlide)){return false;}//do nothing
      this.setup();
   },
   
   setup: function(){
      var o = this.options;
      o.sliderElements = (o.objToSlide.getElements(o.sliderElements));
      if(!(o.sliderElements.length>0)){return false;}//do nothing
      o.leftBtn = $(o.leftBtn);
      o.rightBtn = $(o.rightBtn);
      o.objToSlide.setStyles({
         position: 'relative',
         left: 0
      });
      var element = $(o.sliderElements[0]);
      var margins = parseFloat(element.getStyle('margin-left')) + parseFloat(element.getStyle('margin-right'));
      var marginsV = parseFloat(element.getStyle('margin-top')) + parseFloat(element.getStyle('margin-bottom'));
      var size  = element.getSize();
      o.elementWidth = size.x + margins;
      o.elementHeight = size.y + marginsV;
      var maskDim = o.objToSlide.getParent().getSize();
      o.objToSlide.getParent().setStyle('overflow', 'hidden');
		if(o.isHorizontal){
			o.objToSlide.setStyle('width', (o.elementWidth * o.sliderElements.length));
			o.numOfElementsShown = Math.ceil(maskDim.x /o.elementWidth);
		}else{
			o.objToSlide.setStyle('height', (o.elementHeight * o.sliderElements.length));
			o.numOfElementsShown = Math.ceil(maskDim.y / o.elementHeight);
		}
      o.index = 0;
      o.total = o.sliderElements.length - o.numOfElementsShown;
      o.totalMoves = -(o.total / o.numOfElementsToSlide);
      o.myFx = new Fx.Morph(o.objToSlide, {duration: 500, transition: o.easing, link: 'chain'});
      if(o.leftBtn){
     		o.leftBtn.addEvent("click", this.leftClick.bindWithEvent(this));
   	}
   	if(o.rightBtn){
      	o.rightBtn.addEvent("click", this.rightClick.bindWithEvent(this));
   	}
   	if(o.useMouseWheel){
      	o.objToSlide.addEvent('mousewheel', this.mouseWheel.bindWithEvent(this));
   	}
   	this.fireEvent('onSlideComplete', {index:this.getAbsIndex(), total:this.options.sliderElements.length});
   },
   
   mouseWheel: function(e){
		e.stop(); // prevent the mousewheel from scrolling the page.
		if (e.wheel < 0){
			this.rightClick();
		} else {
			this.leftClick();
		}
   },
   
   leftClick: function(e){
   	if(e){e.stop();}
      if(this.sliding){return;}
      var o = this.options;
      var newPos;
      o.index += 1;
      if(o.isHorizontal){
	      if(o.index < 0){
	         newPos = (o.elementWidth * o.numOfElementsToSlide)*o.index;
	      }else{
	         o.index = 0;
	         newPos = 0;
	      }
      }else{
	      if(o.index < 0){
	         newPos = (o.elementHeight * o.numOfElementsToSlide)*o.index;
	      }else{
	         o.index = 0;
	         newPos = 0;
	      }
      }
   	this.slide(newPos);
   },
   
   rightClick: function(e){
   	if(e){e.stop();}
      if(this.sliding){return;}
      var o = this.options;
      var newPos;
      o.index -= 1;
      if(o.isHorizontal){
	      if(o.index >= o.totalMoves){
	         newPos = (o.elementWidth * o.numOfElementsToSlide)*o.index;
	      }else{
	         o.index = o.totalMoves;
	         newPos = (o.elementWidth * o.numOfElementsToSlide)*o.index;
	      }
      }else{
      	if(o.index >= o.totalMoves){
	         newPos = (o.elementHeight * o.numOfElementsToSlide)*o.index;
	      }else{
	         o.index = o.totalMoves;
	         newPos = (o.elementHeight * o.numOfElementsToSlide)*o.index;
	      }
      }
      this.slide(newPos);
   },
   
   slide: function(newPos){
      var o = this.options;
      var cur = (o.isHorizontal) ? (o.objToSlide.getCoordinates(o.objToSlide.getParent()).left) : (o.objToSlide.getCoordinates(o.objToSlide.getParent()).top);
      if(cur == newPos){return false;}
      this.sliding = true;
      if(this.options.isHorizontal){
	      this.options.myFx.start({
	         'left': newPos
	      }).chain(function(){
	         this.sliding = false;
	         this.fireEvent('onSlideComplete', {index:this.getAbsIndex(), total:this.options.sliderElements.length});
	      }.bind(this));
      }else{
      	this.options.myFx.start({
	         'top': newPos
	      }).chain(function(){
	         this.sliding = false;
	         this.fireEvent('onSlideComplete', {index:this.getAbsIndex(), total:this.options.sliderElements.length});
	      }.bind(this));
      }
   },
   
   slideTo: function(pos){
      if($type(pos) != "number"){return false;}
      var o = this.options;
      pos = pos + 1;
      var newPos;
      if(pos <= o.numOfElementsShown){
         o.index = 0;
      }else{
         o.index = -(((pos - o.numOfElementsShown) / o.numOfElementsToSlide).round());
      }
      if(o.isHorizontal){
	      if(o.index >= o.totalMoves){
	         newPos = (o.elementWidth * o.numOfElementsToSlide)*o.index;
	      }else{
	         o.index = o.totalMoves;
	         newPos = (o.elementWidth * o.numOfElementsToSlide)*o.index;
	      }
      }else{
	      if(o.index >= o.totalMoves){
	         newPos = (o.elementHeight * o.numOfElementsToSlide)*o.index;
	      }else{
	         o.index = o.totalMoves;
	         newPos = (o.elementHeight * o.numOfElementsToSlide)*o.index;
	      }
      }
      this.slide(Math.min(0,newPos));
   },
   
   getAbsIndex:function(){
      return (Math.abs(this.options.index) + 1);
   }
});